package com.excilys.capicsoubank.client;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Method;

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;
import org.apache.ws.security.handler.WSHandlerConstants;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import transfer.Transfer;

import com.excilys.capicsoubank.webservices.soap.AccountDTO;
import com.excilys.capicsoubank.webservices.soap.TransferWebService;
import com.excilys.capicsoubank.webservices.soap.UserWebService;
import com.excilys.capicsoubank.webservices.soap.impl.TransferWebServiceImplService;
import com.excilys.capicsoubank.webservices.soap.impl.UserWebServiceImplService;

public class MainSOAP {
	private final UserWebService userWebService;
	private final TransferWebService transferWebService;
	private final WSS4JOutInterceptor wss4jOutInterceptor;
	private final UsernamePasswordCallback passwordCallback;
	private boolean quit = false;

	/**
	 * @param args
	 * @throws IOException
	 */
	public static void main(String[] args) throws IOException {
		MainSOAP main = new MainSOAP();
		main.run();
	}

	public MainSOAP() {
		userWebService = new UserWebServiceImplService()
				.getUserWebServiceImplPort();
		transferWebService = new TransferWebServiceImplService()
				.getTransferWebServiceImplPort();

		ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
				"applicationContext.xml");

		wss4jOutInterceptor = ctx.getBean(WSS4JOutInterceptor.class);
		passwordCallback = ctx.getBean(UsernamePasswordCallback.class);

		Client client = ClientProxy.getClient(userWebService);
		client.getOutInterceptors().add(wss4jOutInterceptor);

		client = ClientProxy.getClient(transferWebService);
		client.getOutInterceptors().add(wss4jOutInterceptor);
	}

	public void run() throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

		while (!quit) {
			System.out.print("$ ");
			String command = in.readLine();

			String[] commandSplit = command.split(" ");
			Class<?>[] paramsClass = new Class[commandSplit.length - 1];
			Object[] params = new Object[commandSplit.length - 1];

			for (int i = 1; i < commandSplit.length; i++) {
				paramsClass[i - 1] = String.class;
				params[i - 1] = commandSplit[i];
			}

			try {
				Method method = MainSOAP.class.getDeclaredMethod(
						commandSplit[0] + "Method", paramsClass);
				method.invoke(this, params);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	private void credentialsMethod(String username, String password) {
		wss4jOutInterceptor.setProperty(WSHandlerConstants.USER, username);
		passwordCallback.setPassword(username, password);
	}

	private void quitMethod() {
		quit = true;
	}

	private void accountsMethod() {
		System.out.println("Accounts :");
		for (AccountDTO accountDTO : userWebService.getAccounts())
			System.out.println(new StringBuilder("\tN°")
					.append(accountDTO.getAccountId()).append("\t")
					.append(accountDTO.getLabel()).append("\t")
					.append(accountDTO.getBalance() / 100).append(",")
					.append(accountDTO.getBalance() % 100).toString());
	}

	private void transferMethod(String accountSourceId,
			String accountDestinationId, String amount) {
		try {
			Transfer transfer = new Transfer();
			transfer.setAccountSourceId(Integer.parseInt(accountSourceId));
			transfer.setAccountDestinationId(Integer
					.parseInt(accountDestinationId));
			transfer.setAmount(Long.parseLong(amount));

			com.excilys.capicsoubank.webservices.soap.Transfer arg0 = new com.excilys.capicsoubank.webservices.soap.Transfer();
			arg0.setArg0(transfer);
			transferWebService.transfer(arg0);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
